Android OpenGL的简单使用(4):深度测试

Posted by alonealice on 2020-12-25
深度和深度测试

深度其实就是该像素点在3d世界中距离摄象机的距离 , 深度值越大,则离摄像机越远。摄像机可能放在坐标系的任何位置,不能简单地说像素的z坐标越大或越小就是越靠近摄像机。

在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的。比如下图中的A、B,先绘制A,再绘制B,A就有一部分被B挡住。而有了深度缓冲以后,绘制物体的顺序就不那么重要了,都能按照远近(Z值)正常显示

启动深度测试

启动深度测试需要打开深度测试功能,调用glEnable(GL_DEPTH_TEST)打开,然后调用glDepthFunc(int func)方法指定深度测试模式。func可取以下值:

1
2
3
4
5
6
7
- GL10.GL_NEVER:不通过
- GL10.GL_LESS:如果输入的深度值小于参考值,则通过
- GL10.GL_EQUAL:如果输入的深度值等于参考值,则通过
- GL10.GL_LEQUAL:如果输入的深度值小于或等于参考值,则通过
- GL10.GL_GREATER :如果输入的深度值大于参考值,则通过
- GL10.GL_GEQUAL:如果输入的深度值大于或等于参考值,则通过
- GL10.GL_ALWAYS:总是通过

通过表示会绘制,否则不绘制。比如设置坐标的点z位置为0.5

1
private float[] mArray = { 0f, 0f, 0.5f };

设置深度为0.1

1
2
3
4
5
6
7
8
// Surface创建的时候调用
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 设置清屏颜色为黑色
gl.glClearColor(0f, 0f, 0f, 0f);
// 设置深度
gl.glClearDepthf(0.1f);
}

在onDrawFrame中清除屏幕:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    // 在Surface上绘制的时候调用
@Override
public void onDrawFrame(GL10 gl) {

// 清除屏幕
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);

// 允许设置顶点 // GL10.GL_VERTEX_ARRAY顶点数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

//开启深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);

//指定深度测试模式
gl.glDepthFunc(GL10.GL_GREATER);

// 设置顶点
gl.glVertexPointer(1, GL10.GL_FLOAT, 0, mBuffer);

//设置点的颜色为绿色
gl.glColor4f(0f, 1f, 0f, 0f);

//设置点的大小
gl.glPointSize(80f);

// 绘制点
gl.glDrawArrays(GL10.GL_POINTS, 0, 1);

//关闭深度测试
gl.glDisable(GL10.GL_DEPTH_TEST);

// 取消顶点设置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

}
}

指定深度测试模式为GL_GREATER,即如果输入的深度值大于参考值,则通过。这里0.5>0.1,通过。

如果把深度设置为1f

1
2
3
4
5
6
7
8
// Surface创建的时候调用
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 设置清屏颜色为黑色
gl.glClearColor(0f, 0f, 0f, 0f);
// 设置深度
gl.glClearDepthf(1f);
}

此时0.5<1,不通过,则不会被绘制出来。